package com.eastfair.venuebooking.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.eastfair.annotation.annotation.base.BaseControllerInfo;
import com.eastfair.annotation.annotation.log.SysLog;
import com.eastfair.annotation.annotation.security.PreAuth;
import com.eastfair.boot.controller.SuperController;
import com.eastfair.boot.request.PageParams;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.echo.core.EchoService;
import com.eastfair.pay.dto.InvoiceCallbackDTO;
import com.eastfair.venuebooking.demand.ContractManageGroup;
import com.eastfair.venuebooking.dto.*;
import com.eastfair.venuebooking.entity.ContractManage;
import com.eastfair.venuebooking.service.ContractManageService;
import com.eastfair.venuebooking.vo.ContractManageVO;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotEmpty;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>
 * 前端控制器
 * 合同
 * </p>
 *
 * @author lyw
 * @date 2022-06-20
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/contractManage")
@Api(value = "ContractManage", tags = "合同")
@PreAuth(replace = "venuebooking:contractManage:")
public class ContractManageController extends SuperController<ContractManageService, Long, ContractManage, ContractManagePageQuery, ContractManageSaveDTO, ContractManageUpdateDTO> {

    @Resource
    private EchoService echoService;

    @Resource
    private ContractManageService contractManageService;

    @Override
    public void handlerResult(IPage<ContractManage> page) {
        // 想让返回值实现自动回显，请将此行代码打开
        // echoService.action(page);
    }

    /**
     * Excel导入后的操作
     *
     * @param list
     */
    @Override
    public R<Boolean> handlerImport(List<Map<String, String>> list) {
        List<ContractManage> contractManageList = list
                .stream()
                .map((map) -> ContractManage.builder().build())
                .collect(Collectors.toList());
        return R.success(baseService.saveBatch(contractManageList));
    }

    /**
     * 处理参数
     *
     * @param params 分页参数
     */
    @Override
    public void handlerQueryParams(PageParams<ContractManagePageQuery> params) {
        ContractManagePageQuery pageQuery = params.getModel();
        //分页处理
        if (ContextUtil.getProjectId() != null) {
            pageQuery.setProjectId(ContextUtil.getProjectId());
        }
    }

    /**
     * 查询合同列表.
     *
     * @param pageParams the page params
     * @return the r
     */
    @PostMapping("/page/contractManage")
    @BaseControllerInfo(voGroup = ContractManageGroup.QueryContract.class)
    public R<IPage<ContractManageVO>> queryContract(@RequestBody PageParams<ContractManageQuery> pageParams) {
        log.info("pageContract - 查询合同列表, pageParams={}", pageParams);
        return R.successDef(contractManageService.listContractManageVOs(pageParams));
    }

    /**
     * 查询我的合同列表.
     *
     * @param pageParams the page params
     * @return the r
     */
    @PostMapping("/page/me/contractManage")
    @BaseControllerInfo(voGroup = ContractManageGroup.QueryContract.class)
    public R<IPage<ContractManageVO>> queryMeContract(@RequestBody PageParams<ContractManageQuery> pageParams) {
        log.info("pageContract - 查询合同列表, pageParams={}", pageParams);
        ContractManageQuery query = pageParams.getModel();
        query.setBelongTo(ContextUtil.getUserId());
        return R.successDef(contractManageService.listContractManageVOs(pageParams));
    }

    /**
     * id查询合同.
     *
     * @param id the id
     * @return the r
     */
    @GetMapping("/get/{id}")
    public R<ContractManageVO> getById(@PathVariable("id") Long id) {
        log.info("getById - id查询合同, id={}", id);
        return R.successDef(contractManageService.getContractManageVOById(id));
    }

    /**
     * 合同编号获取合同VO.
     *
     * @param contractNumber the contract number
     * @return the by contract number
     */
    @GetMapping("/get/contractNumber/{contractNumber}")
    public R<ContractManageVO> getByContractNumber(@PathVariable("contractNumber") String contractNumber) {
        log.info("getByContractNumber - 合同编号获取合同VO, contractNumber={}", contractNumber);
        return R.successDef(contractManageService.getVOByContractNumber(contractNumber));
    }

    /**
     * 新增合同.
     *
     * @param dto the save dto
     * @return the r
     */
    @SysLog("新增合同")
    @PostMapping("/save")
    public R<Boolean> saveContract(@RequestBody @Validated({ContractManageDTO.Save.class}) ContractManageDTO dto) throws ClassNotFoundException {
        log.info("saveContract - 新增合同, dto={}", dto);
        return R.successDef(contractManageService.saveContract(dto));
    }

    /**
     * 编辑合同.
     *
     * @param dto the dto
     * @return the r
     */
    @SysLog("修改合同")
    @PostMapping("/update")
    public R<Boolean> updateContract(@RequestBody
                                     @Validated({ContractManageDTO.Save.class, ContractManageDTO.Update.class})
                                     ContractManageDTO dto) {
        log.info("updateContract - 编辑合同, dto={}", dto);
        return R.successDef(contractManageService.updateContract(dto));
    }

    /**
     * 移除合同.
     *
     * @param ids the ids
     * @return the r
     */
    @SysLog("移除合同")
    @PostMapping("/remove")
    public R<Boolean> deleteContract(@RequestBody @NotEmpty(message = "合同id不可为空") List<Long> ids) {
        log.info("removeContract - 删除合同, ids={}", ids);
        return R.successDef(contractManageService.removeContractByIds(ids));
    }

    /**
     * 分配合同.
     *
     * @param assignDTO the assign dto
     * @return the r
     */
    @SysLog("分配合同")
    @PostMapping("/assign")
    public R<Boolean> updateAssign(@RequestBody @Validated({ContractManageDTO.Assign.class})
                                   ContractManageAssignDTO assignDTO) {
        log.info("assign - 分配合同, assignDTO={}", assignDTO);

        return R.successDef(contractManageService.updateBelongTo(assignDTO));
    }

    /**
     * 认款/取消认款 之后更新合同.
     *
     * @param contractManageDTO the contract manage dto
     * @return the r
     */
    @PostMapping("/update/collect")
    public R<Boolean> updateForCollect(@RequestBody @Validated({ContractManageDTO.Collect.class})
                                       ContractManageDTO contractManageDTO) {
        log.info("updateForCollect - 认款/取消认款后更新合同, contractManageDTO={}", contractManageDTO);
        try {
            return R.successDef(contractManageService.updateContractForCollect(contractManageDTO));
        } catch (BizException e) {
            return R.fail(e);
        }
    }

    /**
     * 开票回填
     *
     * @param invoiceCallbackDTO
     * @return the r
     */
    @PostMapping("/update/invoiceAmount")
    public R<Boolean> updateForInvoice(@RequestBody @Validated InvoiceCallbackDTO invoiceCallbackDTO) {
        log.info("updateForInvoice - 开票回填, invoiceCallbackDTO={}", invoiceCallbackDTO);
        contractManageService.updateForInvoice(invoiceCallbackDTO);
        return R.success();
    }


    /**
     * 确认合同.
     *
     * @param id the id
     * @return the r
     */
    @SysLog("确认合同")
    @GetMapping("/contractStatus/approved/{id}")
    public R<Boolean> updateContractStatusApproved(@PathVariable("id") Long id) {
        log.info("updateContractStatusApproved - 确认合同, id={}", id);
        return R.successDef(contractManageService.updateContractStatusApproved(id));
    }

    /**
     * 批量ID更新合同为失效.
     *
     * @param ids the ids
     * @return the r
     */
    @SysLog("作废合同")
    @PostMapping("/batch/contractStatus/cancel")
    public R<Boolean> updateContractStatusCancel(@RequestBody List<Long> ids) {
        log.info("updateContractStatusCancel - 批量ID更新合同为失效, ids={}", ids);
        return R.successDef(contractManageService.updateContractDisableByIds(ids));
    }

    /**
     * 计划付款时间范围查询未付款的合同.
     *
     * @param startPlanPayTime the start plan pay time
     * @param endPlanPayTime   the end plan pay time
     * @return the r
     */
    @GetMapping("/query/planPayTime")
    public R<List<ContractManageVO>> queryByPlanPayTime(@RequestParam("startPlanPayTime") String startPlanPayTime,
                                                        @RequestParam("endPlanPayTime") String endPlanPayTime) {
        log.info("queryByPlanPayTime - 计划付款时间范围查询未付款的合同, startPlanPayTime={}, endPlanPayTime={}", startPlanPayTime, endPlanPayTime);
        return R.successDef(contractManageService.listByPlanPayTime(startPlanPayTime, endPlanPayTime));
    }
}
